package io.oschina.binv.kapp.framework

import android.Manifest
import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.support.v7.widget.AppCompatCheckBox
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.*
import io.oschina.binv.kapp.R
import io.oschina.binv.kapp.framework.extend.commonAdapter
import io.oschina.binv.kapp.framework.extend.printOrReport
import io.reactivex.Observable
import io.reactivex.functions.Consumer
import io.oschina.binv.kapp.framework.widget.*


/**
 * create an instance of this fragment.
 */
class MediaPickerFragment : BaseFragment() {

    val backIv by lazy {
        findViewById<ImageView>(R.id.btn_back)
    }
    val folderRv by lazy {
        findViewById<RecyclerView>(R.id.rv_folder)
    }
    val mediaItemRv by lazy {
        findViewById<RecyclerView>(R.id.rv_media_item)
    }

    val folderPop by lazy {
        findViewById<RelativeLayout>(R.id.rl_folder_pop)
    }
    val dirTv by lazy {
        findViewById<TextView>(R.id.tv_dir)
    }
    val rl_dir by lazy {
        findViewById<RelativeLayout>(R.id.rl_dir)
    }
    val previewTv by lazy {
        findViewById<TextView>(R.id.btn_preview)
    }
    val okBtn by lazy {
        findViewById<Button>(R.id.btn_ok)
    }


    override fun setContentView(inflater: LayoutInflater, container: ViewGroup?): View {
        return inflater.inflate(R.layout.fragment_media_picker, container, false)
    }



    companion object {
        val PAYLOAD_HASE_CAMERA = "PAYLOAD_OPEN_CAMERA"
        val PAYLOAD_SELECT_ITEMS="PAYLOAD_SELECT_ITEMS"
        val PAYLOAD_SELECT_LIMIT="PAYLOAD_SELECT_LIMIT"
        val PAYLOAD_SELECT_FOLDER_POSITION="PAYLOAD_SELECT_FOLDER_POSITION"
    }

    init {
        //必须放置此处,否则因为用户操作,或androi生命周期原因会多次执行,导致内存泄露(DESTROY后,才会销毁)
        RxBus.toObservable(SelectItemsEvent::class.java)
                .compose(ioToMain())
                .subscribe(Consumer {
                    data->
                    syncSelectItems(data.selectItems)
                    updateOkBtn()
                    //预防视图已销毁
                    isViewActiveRunNow {
                        mediaItemRv.adapter.notifyDataSetChanged()
                    }
                },Consumer {
                    t->t.printStackTrace()
                })
    }

    //外部传递值
    var payloadHaseCamera=false;
    var payloadSelectItems= arrayListOf<MediaItem>()
    var payloadSelectLimit=1
    var selectFolderPosition=0
    //适配器内部的状态值,不保存
    val mediaFolders= mutableListOf<MediaFolder>()
    val mediaItems= arrayListOf<MediaItem>()

    override fun initViewsAndLocalData(savedBundle: Bundle): (outBundle: Bundle) -> Unit {
        payloadHaseCamera=savedBundle.getBoolean(PAYLOAD_HASE_CAMERA,false)
        try {
            payloadSelectItems=savedBundle.getParcelableArrayList<MediaItem>(PAYLOAD_SELECT_ITEMS)
        }catch (ex:Throwable){
            context.printOrReport(ex)
        }
        if(payloadSelectItems==null){
            payloadSelectItems= arrayListOf<MediaItem>()
        }
        payloadSelectLimit=savedBundle.getInt(PAYLOAD_SELECT_LIMIT,1)
        selectFolderPosition=savedBundle.getInt(PAYLOAD_SELECT_FOLDER_POSITION,0)

        backIv.setOnClickListener{finish()}
        okBtn.setOnClickListener{_->
            RxBus.post(SelectItemsEvent(payloadSelectItems))
            finish()
        }
        //初始化完成按钮状态
        updateOkBtn()

        //设置媒体文件九宫格
        /** 根据屏幕宽度与密度计算GridView显示的列数， 最少为三列，并获取Item宽度  */
        val screenWidth = context.resources.displayMetrics.widthPixels
        val densityDpi = context.resources.displayMetrics.densityDpi
        var cols = screenWidth / densityDpi
        cols = if (cols < 3) 3 else cols
        //val columnSpace = (2 * context.resources.displayMetrics.density).toInt()
        //2dp->?px
        val columnSpace= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, context.getResources().getDisplayMetrics()).toInt()

        val imageItemWidth= (screenWidth - columnSpace * (cols - 1)) / cols

        mediaItemRv.setLayoutManager(GridLayoutManager(context, cols))
        mediaItemRv.addItemDecoration(object :RecyclerView.ItemDecoration(){
            override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
                //不是第一个的格子都设一个左边和底部的间距
                outRect.left = columnSpace
                outRect.bottom = columnSpace
                //由于每行都只有spanCount个，所以第一个都是spanCount的倍数，把左边距设为0
                if (parent.getChildLayoutPosition(view) % cols == 0) {
                    outRect.left = 0
                }
            }
        })

        mediaItemRv.adapter=context.commonAdapter(R.layout.fragment_media_picker_media_item,mediaItems){
            holder, data, position->
            holder.convertView.setLayoutParams(AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, imageItemWidth)); //让图片是个正方形
            val checkAccb=holder.getView<AppCompatCheckBox>( R.id.accb_check)
            val thumbIv=holder.getView<ImageView>( R.id.iv_thumb)
            val maskV= holder.getView<View>(R.id.v_mask)
            MediaPicker.instance.displayMedia(data,thumbIv)
            maskV.setOnClickListener{_->
                gotoImagePreview(data,position)
            }
            thumbIv.setOnClickListener{_->
                gotoImagePreview(data,position)
            }

            val checkViewFl=holder.getView<FrameLayout>( R.id.fl_checkView)
            //设置选中状态
            checkAccb.isChecked=data.select
            if(checkAccb.isChecked) {
                maskV.visibility=View.VISIBLE
            } else {
                maskV.visibility=View.GONE
            }
            //点击改选中状态
            checkViewFl.setOnClickListener{_->
                if(checkAccb.isChecked ){
                    //更新界面和数据状态
                    maskV.visibility=View.GONE
                    checkAccb.isChecked = false
                    data.select=false
                    //维护选中列表
                    payloadSelectItems.remove(data)
                    updateOkBtn()
                } else if(payloadSelectItems.size<payloadSelectLimit && !payloadSelectItems.contains(data)){
                    //更新界面和数据状态
                    maskV.visibility=View.VISIBLE
                    checkAccb.isChecked = true
                    data.select=true
                    //维护选中列表
                    payloadSelectItems.add(data)
                    updateOkBtn()
                }
            }
            val videoIconIv= holder.getView<ImageView>(R.id.iv_video_icon)
            val videoDurationTv=holder.getView<TextView>(R.id.tv_video_duration)
            if(data.mediaType==MEDIA_VIDEO){
                maskV.visibility=View.GONE
                checkViewFl.visibility=View.GONE

                videoIconIv.visibility=View.VISIBLE
                videoDurationTv.visibility=View.VISIBLE
                videoDurationTv.text=String.format("%01d:%02d",((data.duration/1000)/60).toInt(),((data.duration/1000)%60).toInt())
            }else{
                checkViewFl.visibility=View.VISIBLE
                videoIconIv.visibility=View.GONE
                videoDurationTv.visibility=View.GONE
            }
        }
        //设置文件夹列表适配器
        val linearLayoutManager = LinearLayoutManager(context)
        linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
        folderRv.setLayoutManager(linearLayoutManager)
        folderRv.itemAnimator.changeDuration=0// 通过设置动画执行时间为0来解决闪烁问题
        folderRv.adapter=context.commonAdapter(R.layout.fragment_media_picker_folder_item,mediaFolders){
            holder, data, position->
            holder.setText(R.id.tv_folder_name,data.name)
            holder.setText(R.id.tv_image_count,String.format(resources.getString(R.string.mp_folder_image_count), data.mediaItems.size))
            MediaPicker.instance.displayMedia(data.mediaItems[0],holder.getView<ImageView>( R.id.iv_cover))
            if(data.name==dirTv.text){
                //选择当前文件夹
                selectFolderPosition=position
                holder.setChecked(R.id.accb_folder_check,true)
            }else{
                holder.setChecked(R.id.accb_folder_check,false)
            }

            holder.getView<LinearLayout>(R.id.ll_folder_item).setOnClickListener{_->
                if(selectFolderPosition!=position){
                    dirTv.setText(data.name)
                    //取消选择之前的文件夹
                    folderRv.adapter.notifyItemChanged(selectFolderPosition)

                    //改变选择的文件夹,并刷新图片列表
                    selectFolderPosition=position
                    holder.setChecked(R.id.accb_folder_check,true)
                    mediaItems.clear()
                    mediaItems.addAll(data.mediaItems)
                    mediaItemRv.adapter.notifyDataSetChanged()
                    //选中后隐藏
                    exitAnimator()
                }
            }
            //视频覆盖播放图标
            if(data.name==resources.getString(R.string.mp_all_vidoes)){
                holder.getView<ImageView>(R.id.iv_video_play).visibility=View.VISIBLE
            }else{
                holder.getView<ImageView>(R.id.iv_video_play).visibility=View.GONE
            }
        }
        //点击边缘隐藏
        folderPop.setOnClickListener{_ -> exitAnimator()}
        //点击弹出或隐藏
        rl_dir.setOnClickListener{_ ->
            if(folderPop.visibility==View.GONE){
                enterAnimator()
            }else {
                exitAnimator()
            }
        }
        previewTv.setOnClickListener { _->
            if(payloadSelectItems.size>0){
                openImagePreview(payloadSelectItems,0,payloadSelectLimit)
            }
        }
        return  {
            outBundle ->
            try {
                //外部,传递值,未变化的可不更新
                outBundle.putParcelableArrayList(PAYLOAD_SELECT_ITEMS, payloadSelectItems)
                outBundle.putInt(PAYLOAD_SELECT_FOLDER_POSITION,selectFolderPosition)
            }catch (ex:Throwable){
                context.printOrReport(ex)
            }
        }
    }

    private fun updateOkBtn(){
        //预防视图已销毁
        isViewActiveRunNow {
            //再次初始化完成按钮状态
            if(payloadSelectItems.size==0) okBtn.apply {
                text=resources.getString(R.string.mp_complete)
                isEnabled=false
            }
            else okBtn.apply {
                text=String.format(resources.getString(R.string.mp_select_complete),payloadSelectItems.size, payloadSelectLimit)
                isEnabled=true
            }
        }
    }

    //同步传递的选择值的各种状态
    private fun syncSelectItems(selectItems:ArrayList<MediaItem>){
        //mediaItem为引用，改变全部，一遍即可
        if(mediaFolders.size>0){
            payloadSelectItems.clear()
            mediaFolders[0].mediaItems.forEach{
                item-> item.select=false
                for(selectItem in selectItems){
                    if(selectItem==item){
                        item.compressPath=selectItem.compressPath
                        if(payloadSelectItems.size<payloadSelectLimit && !payloadSelectItems.contains(item)){
                            item.select=true
                            payloadSelectItems.add(item)
                        }
                        break
                    }
                }
            }
        }
    }
    override fun loadRemoteData() {
        requestPermissionRunAsync(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)){
            //异步请求文件夹列表
            Observable.just(MediaPicker.getMediaWithMediaFolder(context,null,""))
                    .compose(ioToMain())
                    . subscribe(Consumer {
                        datas->
                        if (datas.size>0){
                            syncSelectItems(datas[0].mediaItems)
                            updateOkBtn()
                            //选择该文件夹

                            mediaFolders.clear()
                            mediaFolders.addAll(datas)

                            mediaItems.clear()
                            mediaItems.addAll(datas[0].mediaItems)
                            isViewActiveRunNow {
                                if(selectFolderPosition>=0 && selectFolderPosition<datas.size){
                                    dirTv.text=datas[selectFolderPosition].name
                                }
                                folderRv.adapter.notifyDataSetChanged()
                                mediaItemRv.adapter.notifyDataSetChanged()
                            }
                        }else{
                            throw Exception("fin mediaFolders.size ==0")
                        }
                    },Consumer {
                        ex->context.printOrReport(ex)
                    })
        }
    }
    private fun enterAnimator() {
        val alpha = ObjectAnimator.ofFloat(folderPop, "alpha", 0f, 1f)
        val translationY = ObjectAnimator.ofFloat(folderRv, "translationY", folderRv.getHeight().toFloat(), 0f)
        val set = AnimatorSet()
        set.duration = 400
        set.playTogether(alpha, translationY)
        set.interpolator = AccelerateDecelerateInterpolator()
        set.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {
                folderPop.visibility=View.VISIBLE
                rl_dir.isEnabled=false
            }

            override fun onAnimationEnd(animation: Animator) {
                rl_dir.isEnabled=true
            }

            override fun onAnimationCancel(animation: Animator) {}

            override fun onAnimationRepeat(animation: Animator) {}
        })
        set.start()
    }

    private fun exitAnimator() {
        val alpha = ObjectAnimator.ofFloat(folderPop, "alpha", 1f, 0f)
        val translationY = ObjectAnimator.ofFloat(folderRv, "translationY", 0f, folderRv.getHeight().toFloat())
        val set = AnimatorSet()
        set.duration = 350
        set.playTogether(alpha, translationY)
        set.interpolator = AccelerateDecelerateInterpolator()
        set.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {
                //folderRv.visibility=View.VISIBLE
                rl_dir.isEnabled=false
            }

            override fun onAnimationEnd(animation: Animator) {
                folderPop.visibility=View.GONE
                rl_dir.isEnabled=true
            }

            override fun onAnimationCancel(animation: Animator) {}

            override fun onAnimationRepeat(animation: Animator) {}
        })
        set.start()
    }

    fun gotoImagePreview(data:MediaItem, position:Int){
        if(data.mediaType==MEDIA_VIDEO){
            if(payloadSelectItems.size==0){
                val allVideos= mediaFolders.find { f->f.name==context.getResources().getString(R.string.mp_all_vidoes)}
                if(allVideos!=null && allVideos.mediaItems.size>0){
                    openImagePreview(allVideos.mediaItems,allVideos.mediaItems.indexOf(data),1)
                }
            }
        }else{
            val items=arrayListOf<MediaItem>()
            items .addAll(mediaItems.filter { mi->mi.mediaType==MEDIA_IMAGE})
            openImagePreview(items, position,payloadSelectLimit)
        }
    }
   fun openImagePreview(mediaItems:ArrayList<MediaItem>,position:Int,selectLimit:Int){

       val intent= Intent(context, ReuseActivity::class.java)
       intent.putExtra(ReuseActivity.FRAGMENT_NAME, ImagePreviewFragment::class.java.canonicalName)
       intent.putExtra(ReuseActivity.FRAGMENT_ARGS, Bundle().apply {
           putParcelableArrayList(ImagePreviewFragment.PAYLOAD_SELECT_ITEMS, payloadSelectItems )
           putInt(ImagePreviewFragment.PAYLOAD_SELECT_LIMIT, selectLimit )
           putParcelableArrayList(ImagePreviewFragment.PAYLOAD_SELECT_FOLDER_ITEMS, mediaItems)
           putInt(ImagePreviewFragment.PAYLOAD_SELECT_FOLDER_PREVIEW_POSITION, position )
       })
       startActivity(intent)
   }
}